package com.xyy.saas.payment.service.jd;

import com.xyy.saas.payment.dao.model.BankBillJd0028;
import com.xyy.saas.payment.dao.model.PayFinanceRefundPlan;
import com.xyy.saas.payment.rpc.EcOrderRemote;
import com.xyy.saas.payment.service.BankBillJd0028Service;
import com.xyy.saas.payment.service.impl.JDPayServiceImpl;
import com.xyy.saas.payment.trace.AlarmService;
import com.xyy.saas.payment.trace.DingTalkMessage;
import com.xyy.saas.payment.util.DateUtil;
import com.xyy.saas.payment.util.jdpay.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.util.*;

/**
 * 京东支付宝
 */
@Slf4j
@Component(value = "jDBillServiceImpl0001")
public class JDBillServiceImpl0001 implements JDBillService {

    @Value("${jDBillServiceImpl0001.log.switch:false}")
    private Boolean logSwitch;
    @Autowired
    private BankBillJd0028Service bankBillJd0028Service;
    @Resource
    private EcOrderRemote ecOrderRemote;
    @Autowired
    private AlarmService alarmService;

    @Override
    public void downAndAnalysisBill(String logPrefix, String date) throws Exception {
        log.info("{} JDBillServiceImpl0001#downAndAnalysisBill, {}", logPrefix, date);

        if (StringUtils.isBlank(date)) {
            date = DateUtil.format(new Date(), "yyyyMMdd");
        }
        for (String merchantNo : Arrays.asList(JD_AGGRATE_ALIPAY_PLAT_NO)) {
            if (StringUtils.isNotBlank(merchantNo)) {
                // 1、下载账单
                String fileName = date + "ordercreate_" + merchantNo + ".zip";
                String path = "0001/0001";

                download(logPrefix, getOwner(merchantNo), merchantNo, fileName, path, date);
                // 2、解压账单
                FileUtil.unZip(logPrefix, JDPayServiceImpl.getDownPath(date) + File.separator + fileName, JDPayServiceImpl.getDownPath(date));
                // 3、解析账单并入库
                analysisBill(logPrefix, date, getOwner(merchantNo), merchantNo, "0001", fileName);
            }
        }
    }

    @Override
    public String checkBill(String date) throws Exception {
        // check逻辑同 jDBillServiceImpl0028
        return "";
    }

    @Override
    public int delete(String logPrefix, String billType, String fileName) {
        return bankBillJd0028Service.delete(BankBillJd0028.builder().fileName(fileName).build());
    }

    @Override
    public int insertBatch(String logPrefix, String billType, List<Object> records) {
        fillParam(logPrefix, billType, records);
        return bankBillJd0028Service.insertBatch(records);
    }

    @Override
    public void fillParam(String logPrefix, String billType, List<Object> records) {
        if (CollectionUtils.isEmpty(records)) {
            return;
        }
        long start = System.currentTimeMillis();
        log.info("{} 填充商城数据开始：账单类型{} 数据量{} ", logPrefix, billType, records.size());

        // 退票记录告警
        Set<String> alarmRefundTNoSet = new HashSet<>();
        // 拼装请求数据
        List<String> payNos = new ArrayList<>();
        for (Object record : records) {
            BankBillJd0028 bill = (BankBillJd0028) record;
            if (bill.getOrderType().contains("退款")) {
                payNos.add(bill.getOriOrderNo());
            } else {
                payNos.add(bill.getOrderNo());
            }

            if ("退票".equals(bill.getOrderType())) {
                alarmRefundTNoSet.add(bill.getOriOrderNo());
            }
        }

        if (CollectionUtils.isNotEmpty(alarmRefundTNoSet)) {
            String alarmRefundTNos = String.join(",", alarmRefundTNoSet);
            DingTalkMessage talkMessage = DingTalkMessage.builder().type("京东支付").method("JDBillServiceImpl0001.fillParam").msg("京东支付含退票记录").param("refundNos: " + alarmRefundTNos).build();
            alarmService.alarm(talkMessage);
        }

        // 调用商城接口获取的填充信息dubbo  key：platMerchantNo、value：返回数据
        // Map<String, PayFinanceRefundPlan> resMap = ecOrderRemote.queryListByPayNoMap(payNos);
        Map<String, PayFinanceRefundPlan> resMap = ecOrderRemote.queryListByPayNoMapV2(payNos);
        log.info("{} 填充商城数据获取商城数据结束：账单类型{} 响应数据量{} ", logPrefix, billType, resMap.size());

        // 填充数据
        for (Object record : records) {
            BankBillJd0028 bill = (BankBillJd0028) record;
            String payNo = (bill.getOrderType().contains("退款") ? bill.getOriOrderNo() : bill.getOrderNo());
            PayFinanceRefundPlan result = resMap.get(payNo);
            if (null != result) {
                bill.setReceiveId(result.getBusinessReceiverId()); // 商户编码
                bill.setReceiveName(result.getReceiverName()); // 商户名称
                bill.setUserName(result.getPayerName()); // 客户名称
                bill.setYbmOrderNo(result.getBusinessPayNo()); // 药帮忙订单号
            }
        }
        log.info("{} 填充商城数据完成：账单类型{}，耗时{}ms", logPrefix, billType, System.currentTimeMillis() - start);
    }

    @Override
    public Object parse(String logPrefix, String billType, String owner, String merchantNo, String fileName, String billDate, String line) {
        BankBillJd0028 bankBillJd0028 = new BankBillJd0028();
        // 基本信息
        bankBillJd0028.setOwner(owner);
        bankBillJd0028.setMerchantNo(merchantNo);
        bankBillJd0028.setFileName(fileName);
        bankBillJd0028.setBillDate(billDate);

        // 账单信息
        String[] cols = line.split(",");
        if (Boolean.TRUE.equals(logSwitch)) {
            log.info("{} [jdPay]账单处理, cols:{}", logPrefix, Arrays.toString(cols));
        }
        if (cols.length < 17) {
            log.info("{} [jdPay]账单处理: {}-0001账单，数据行错误，不进行解析：{}-{}", logPrefix, merchantNo, cols.length, line);
            return null;
        }

        bankBillJd0028.setOrderNo(transCol(cols, 0));
        bankBillJd0028.setBankOrderNo(transCol(cols, 1));
        bankBillJd0028.setOrderAmount(StringUtils.isEmpty(transCol(cols, 2)) ? new BigDecimal("0") : new BigDecimal(transCol(cols, 2)));
        bankBillJd0028.setBusinessType(transCol(cols, 3));
        bankBillJd0028.setOrderType(transCol(cols, 4));
        bankBillJd0028.setOrderStatus(transCol(cols, 5));
        bankBillJd0028.setRefundAmount(StringUtils.isEmpty(transCol(cols, 6)) ? new BigDecimal("0") : new BigDecimal(transCol(cols, 6)));
        bankBillJd0028.setSettleStatus(transCol(cols, 7));
        bankBillJd0028.setTradeTime(transCol(cols, 8));
        bankBillJd0028.setDealTime(transCol(cols, 9));
        bankBillJd0028.setOriOrderNo(transCol(cols, 10));
        bankBillJd0028.setFee(StringUtils.isEmpty(transCol(cols, 11)) ? new BigDecimal("0") : new BigDecimal(transCol(cols, 11)));
        bankBillJd0028.setAccountName(transCol(cols, 12));

        // {"merchantNo":"133400097002"}
        // transCol(cols, 13);

        // {"accessType":"MINIAPP"，"sceneType":"ONLINE_APP"，"V_O":"1"，"mptOrder":"1"，"qrExpire":"35940"，"isOnlyDebitCard":"1"，"isNewBizNo":"1"，"subAppId":"2021003155680358"}
        // transCol(cols, 14);

        bankBillJd0028.setBankName(transCol(cols, 15));
        bankBillJd0028.setBusinessOrderNo(transCol(cols, 16));
        bankBillJd0028.setTradeNo("");
        bankBillJd0028.setPlatMerchantNo("");
        bankBillJd0028.setPlatMerchant(merchantNo);
        bankBillJd0028.setPlatMerchantName(transCol(cols, 12));
        bankBillJd0028.setPlatInTransitMerchant(merchantNo);
        bankBillJd0028.setSubMerchant("");
        bankBillJd0028.setCommissionMsg("");
        bankBillJd0028.setMarketingMsg("");
        bankBillJd0028.setCommissionAmount(null);
        bankBillJd0028.setRemark(transCol(cols, 14));
        return bankBillJd0028;
    }

}
